package com.rnkrsoft.suyan.config.server.services.impl;

import com.rnkrsoft.suyan.config.internal.enums.CompareResultEnum;
import com.rnkrsoft.suyan.config.internal.enums.CompareSolutionEnum;
import com.rnkrsoft.suyan.config.internal.enums.ParamStatusEnum;
import com.rnkrsoft.suyan.config.server.config.bo.*;
import com.rnkrsoft.suyan.config.server.config.dao.*;
import com.rnkrsoft.suyan.config.server.config.entity.MachineInfoEntity;
import com.rnkrsoft.suyan.config.server.config.entity.ParamInfoEntity;
import com.rnkrsoft.suyan.config.server.services.compare.domains.*;
import com.rnkrsoft.suyan.config.server.services.compare.services.CompareService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Created by woate on 2019/5/22.
 */
@Service
public class CompareServiceImpl implements CompareService {
    @Autowired
    ProjectInfoDAO projectDAO;
    @Autowired
    EnvironmentInfoDAO environmentDAO;
    @Autowired
    MachineInfoDAO machineDAO;
    @Autowired
    FileInfoDAO fileDAO;
    @Autowired
    ParamInfoDAO paramDAO;


    @Override
    public ToCompareResponse toCompare(ToCompareRequest request) {
        ToCompareResponse response = new ToCompareResponse();
        List<CompareParamByMachineBO> params = paramDAO.compare(request.getSourceMachineId(), request.getMachineId());
        for (CompareParamByMachineBO record : params) {
            String paramName = record.getParamName();

            String sourceParamId = record.getSourceParamId();
            String sourceParamValue = record.getSourceParamValue();
            Integer sourceParamDynamic = record.getSourceParamDynamic();
            Integer sourceParamEncrypt = record.getSourceParamEncrypt();
            String sourceParamDesc = record.getSourceParamDesc();

            String targetParamId = record.getTargetParamId();
            String targetParamValue = record.getTargetParamValue();
            Integer targetParamDynamic = record.getTargetParamDynamic();
            Integer targetParamEncrypt = record.getTargetParamEncrypt();
            String targetParamDesc = record.getTargetParamDesc();

            StringBuilder compareResult = new StringBuilder();
            CompareResultEnum compareResultType = CompareResultEnum.SAME;
            ToCompareParam.ToCompareParamBuilder toCompareParamBuilder = ToCompareParam.builder();
            toCompareParamBuilder.sourceParamId(sourceParamId).targetParamId(targetParamId);
            //来源参数和目标参数均存在的情况
            if (sourceParamId != null && targetParamId != null
            ) {
                if (sourceParamValue != null && !sourceParamValue.equals(targetParamValue)) {
                    compareResultType = CompareResultEnum.DIFFERENCE;
                    compareResult.append("参数值:" + targetParamValue + "  ->  " + sourceParamValue + "<br>");
                }else if (targetParamValue != null && !targetParamValue.equals(sourceParamValue)) {
                    compareResultType = CompareResultEnum.DIFFERENCE;
                    compareResult.append("参数值:" + targetParamValue + "  ->  " + sourceParamValue + "<br>");
                }else if (sourceParamDynamic != null && sourceParamDynamic.compareTo(targetParamDynamic) != 1) {
                    compareResultType = CompareResultEnum.DIFFERENCE;
                    compareResult.append("是否动态参数:" + targetParamDynamic + "  ->  " + sourceParamDynamic + "<br>");
                }else if (targetParamDynamic != null && targetParamDynamic.compareTo(sourceParamDynamic) != 1) {
                    compareResultType = CompareResultEnum.DIFFERENCE;
                    compareResult.append("是否动态参数:" + targetParamDynamic + "  ->  " + sourceParamDynamic + "<br>");
                }else if (sourceParamEncrypt != null && sourceParamEncrypt.compareTo(targetParamEncrypt) != 1) {
                    compareResultType = CompareResultEnum.DIFFERENCE;
                    compareResult.append("是否加密参数:" + targetParamEncrypt + "  ->  " + sourceParamEncrypt + "<br>");
                }else if (targetParamEncrypt != null && targetParamEncrypt.compareTo(sourceParamEncrypt) != 1) {
                    compareResultType = CompareResultEnum.DIFFERENCE;
                    compareResult.append("是否加密参数:" + targetParamEncrypt + "  ->  " + sourceParamEncrypt + "<br>");
                }else if (sourceParamDesc != null && !sourceParamDesc.equals(targetParamDesc)) {
                    compareResultType = CompareResultEnum.DIFFERENCE;
                    compareResult.append("参数描述:" + targetParamDesc + "  ->  " + sourceParamDesc + "<br>");
                }else if (targetParamDesc != null && !targetParamDesc.equals(sourceParamDesc)) {
                    compareResultType = CompareResultEnum.DIFFERENCE;
                    compareResult.append("参数描述:" + targetParamDesc + "  ->  " + sourceParamDesc + "<br>");
                }else{
                    compareResultType = CompareResultEnum.SAME;
                }
            } else if (sourceParamId == null && targetParamId != null) {
                //来源值不存在，目标值存在
                compareResultType = CompareResultEnum.MORE;
                compareResult.append("目标参数多余<br>");
            } else if (sourceParamId != null && targetParamId == null) {
                //来源值存在，目标值不存在
                compareResultType = CompareResultEnum.LESS;
                compareResult.append("目标参数缺少<br>");
            }
            ToCompareParam toCompareParam = toCompareParamBuilder.paramName(paramName)
                    .compareResult(compareResult.toString())
                    .compareResultType(compareResultType.getCode())
                    .solution(compareResultType == CompareResultEnum.SAME ? CompareSolutionEnum.NONE.getCode() : CompareSolutionEnum.SYNC.getCode())
                    .build();
            response.getParams().add(toCompareParam);
        }
        response.setMachineId(request.getMachineId());
        response.setSourceMachineId(request.getSourceMachineId());
        return response;
    }

    @Transactional
    @Override
    public UpdateCompareResponse updateCompare(UpdateCompareRequest request) {
        System.out.println(request);
        UpdateCompareResponse response = new UpdateCompareResponse();
        MachineInfoEntity sourceMachineEntity = machineDAO.selectByPrimaryKey(request.getSourceMachineId());
        MachineInfoEntity targetMachineEntity = machineDAO.selectByPrimaryKey(request.getMachineId());
        for (UpdateCompareParam record : request.getParams()) {
            if (CompareSolutionEnum.valueOfCode(record.getSolution()) == CompareSolutionEnum.NONE) {
                continue;
            }
            CompareResultEnum compareResult = CompareResultEnum.valueOfCode(record.getCompareResultType());
            if (compareResult == CompareResultEnum.DIFFERENCE) {
                ParamInfoEntity paramInfoEntity = paramDAO.selectByPrimaryKey(record.getSourceParamId());
                if (paramInfoEntity != null){
                    ParamInfoEntity newParamEntity = ParamInfoEntity.builder()
                            .paramId(paramInfoEntity.getParamId())
                            .paramValue(paramInfoEntity.getParamValue())
                            .paramDataType(paramInfoEntity.getParamDataType())
                            .paramType(paramInfoEntity.getParamType())
                            .paramDesc(paramInfoEntity.getParamDesc())
                            .paramExtends(paramInfoEntity.getParamExtends())
                            .paramEncrypt(paramInfoEntity.getParamEncrypt())
                            .paramDynamic(paramInfoEntity.getParamDynamic())
                            .paramSystemProperties(paramInfoEntity.getParamSystemProperties())
                            .paramVersion(1)
                            .paramLastUpdater(request.getLoginUserId())
                            .paramStatus(ParamStatusEnum.NORMAL.getCode())
                            .build();
                    paramDAO.updateByPrimaryKeySelective(newParamEntity);
                }
            } else if (compareResult == CompareResultEnum.LESS) {
                //TODO 新增缺失参数
                ParamInfoEntity paramInfoEntity = paramDAO.selectByPrimaryKey(record.getSourceParamId());
                if (paramInfoEntity != null) {
                    paramDAO.insertSelective(ParamInfoEntity.builder()
                            .projectId(targetMachineEntity.getProjectId())
                            .environmentId(targetMachineEntity.getEnvironmentId())
                            .machineId(targetMachineEntity.getMachineId())
                            .paramName(paramInfoEntity.getParamName())
                            .paramValue(paramInfoEntity.getParamValue())
                            .paramDataType(paramInfoEntity.getParamDataType())
                            .paramType(paramInfoEntity.getParamType())
                            .paramDesc(paramInfoEntity.getParamDesc())
                            .paramExtends(paramInfoEntity.getParamExtends())
                            .paramEncrypt(paramInfoEntity.getParamEncrypt())
                            .paramDynamic(paramInfoEntity.getParamDynamic())
                            .paramSystemProperties(paramInfoEntity.getParamSystemProperties())
                            .paramVersion(0)
                            .paramCreator(request.getLoginUserId())
                            .paramLastUpdater(request.getLoginUserId())
                            .paramStatus(ParamStatusEnum.NORMAL.getCode())
                            .build());
                }
            } else if (compareResult == CompareResultEnum.MORE) {
                //TODO 删除多余参数
                paramDAO.deleteByPrimaryKey(record.getTargetParamId());
            }
        }
        return response;
    }
}
